package com.atguigu.tingshu.album.service.impl;


import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.common.anno.GuiGuCache;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;


import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumAttributeValueService albumAttributeValueService;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Transactional
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        //保存专辑基本数据
        Long userId = AuthContextHolder.getUserId();
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setUserId(userId);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);

        //付费专辑需要设置试听的声音的集数
        String payType = albumInfo.getPayType();
        if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType)) {
            albumInfo.setTracksForFree(5);
        }
        albumInfoMapper.insert(albumInfo);
        //保存专辑的属性值数据
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        List<AlbumAttributeValue> collect = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(albumInfo.getId());
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
            return albumAttributeValue;
        }).collect(Collectors.toList());
        albumAttributeValueService.saveBatch(collect);
        //初始化专辑统计信息数据
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY); //播放量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE); //订阅量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BROWSE); //购买量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);//评论数

        //发送消息
        kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_UPPER, String.valueOf(albumInfo.getId()));
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(Long pageNum, Long pageSize, AlbumInfoQuery albumInfoQuery) {
        albumInfoQuery.setUserId(AuthContextHolder.getUserId());
        IPage<AlbumListVo> page = new Page<>(pageNum, pageSize);
        IPage<AlbumListVo> result = albumInfoMapper.findUserAlbumPage(page, albumInfoQuery);
        return result;
    }

    @Transactional
    @Override
    public void removeAlbumInfo(Long id) {
        //删除专辑基本数据表
        albumInfoMapper.deleteById(id);
        //删除专辑的统计数据
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId,id));
        //删除专辑的属性值数据
        albumAttributeValueService.remove(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,id));

        //发送消息
        kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_LOWER, String.valueOf(id));
    }

    @GuiGuCache(cacheKey = RedisConstant.ALBUM_INFO_PREFIX + "#{#params[0]}",enableLock = true,lockName = RedisConstant.ALBUM_LOCK_SUFFIX + "#{#params[0]}")
    @Override
    public AlbumInfo getAlbumInfo(Long id) {
        return getAlbumInfoFromDB(id);

    }
    public AlbumInfo getAlbumInfoFromDB(Long id) {
        //根据专辑Id查询数据
        AlbumInfo albumInfo = albumInfoMapper.selectById(id);
        //根据专辑的Id查询专辑的属性值数据
        List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueService.list(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));
        albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);
        return albumInfo;
    }

    @Override
    public void updateAlbumInfo(Long id, AlbumInfoVo albumInfoVo) {
        //修改专辑的基本数据
        AlbumInfo albumInfo = albumInfoMapper.selectById(id);
        BeanUtils.copyProperties(albumInfoVo,albumInfo);
        albumInfoMapper.updateById(albumInfo);
        //修改属性值数据
        //先删除之前的的属性值数据
        LambdaQueryWrapper<AlbumAttributeValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlbumAttributeValue::getAlbumId,id);
        albumAttributeValueService.remove(queryWrapper);
        //新增属性值数据
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        List<AlbumAttributeValue> collect = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(id);
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
            return albumAttributeValue;
        }).collect(Collectors.toList());
        albumAttributeValueService.saveBatch(collect);

        String isOpen = albumInfoVo.getIsOpen();
        if("1".equals(isOpen)){
            kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_UPPER, String.valueOf(id));
        }else{
            kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_LOWER,String.valueOf(id));
        }
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList() {
        Long userId = AuthContextHolder.getUserId();
        LambdaQueryWrapper<AlbumInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AlbumInfo::getUserId, userId);
        lambdaQueryWrapper.select( AlbumInfo::getId,AlbumInfo::getAlbumTitle);
        List<AlbumInfo> albumInfoList = albumInfoMapper.selectList(lambdaQueryWrapper);
        return albumInfoList;
    }

    @GuiGuCache(cacheKey = RedisConstant.ALBUM_STAT_PREFIX + "#{#params[0]}",enableLock = true,lockName = RedisConstant.ALBUM_STAT_LOCK + "#{#params[0]}")
    @Override
    public AlbumStatVo getAlbumStatVo(Long albumId) {
        AlbumStatVo albumStatVo = albumStatMapper.getAlbumStatVo(albumId);
        return albumStatVo;
    }


    public void saveAlbumStat(Long albumId, String statType) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statType);
        albumStat.setStatNum(0);
        albumStatMapper.insert(albumStat);
    }


}
